﻿using System;
using System.Collections.Generic;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;


namespace EPiServer.Research.VirtualRoles
{
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class VirtualRolesInit : IInitializableModule, IObservable<PageBase>
    {
        private bool _initialized;
        private static List<IObserver<PageBase>> _observers = new List<IObserver<PageBase>>();
        private static readonly object _syncRoot = new object();

        #region IInitializableModule Members

        public void Initialize(InitializationEngine context)
        {
            if (!_initialized)
            {
                PageBase.PageSetup += new PageSetupEventHandler(PageBase_PageSetup);
                _initialized = true;
            }
        }

        public void Uninitialize(InitializationEngine context) { }

        public void Preload(string[] parameters) { }

        #endregion

        #region IObservable<PageBase> Members

        public IDisposable Subscribe(IObserver<PageBase> observer)
        {
            lock (_syncRoot)
            {
                _observers.Add(observer);
            }
            return new ObserverReference(observer);
        }

        #endregion

        void PageBase_PageSetup(PageBase sender, PageSetupEventArgs e)
        {
            sender.Load += new EventHandler(Page_Load);
        }

        void Page_Load(object sender, EventArgs e)
        {
            if (sender is PageBase)
            {
                lock (_syncRoot)
                {
                    foreach (var observer in _observers)
                    {
                        observer.OnNext(sender as PageBase);
                    }
                }
            }
        }
    }

    class ObserverReference : IDisposable
    {
        private IObserver<PageBase> _observer;
        public ObserverReference(IObserver<PageBase> observer)
        {
            _observer = observer;
        }

        public IObserver<PageBase> Observer
        {
            get
            {
                return _observer;
            }
        }
        #region IDisposable Members

        public void Dispose()
        {
            _observer = null;
        }
        #endregion
    }

}